#include "Brocko.h"


/////////////////////////////////////
// Constructors / Destructors      //
/////////////////////////////////////

CBrocko::CBrocko()
{
	player.setInput(&input);
	player.Init(graphics);

	world.Init(&player, 1, &hImage);

	frames= 0;
	this->playingTime = 0;
	this->menuItem = 1;
	this->splashMenuItem = 1;
	upAlreadyPressed = false;
	downAlreadyPressed = false;
	playing = false;


	msqueue = 0;
	//gettimeofday(&lastTime, 0);
	GetSystemTime(&lastTime);
	lastMsTime = (lastTime.wSecond * 1000) + lastTime.wMilliseconds;
	startTime = (float)timeGetTime();
	
	//splashmenu
	hSplashMenu = new HANDLE[3];
	for(int i = 1; i<=4;i++)
	{
		stringstream ss;
		ss << "res/Splash Menu/SplashMenu"<< i <<".bmp";
		hSplashMenu[i-1] = LoadImage(NULL, ss.str().c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	}
	
	//menu
	hMenu = new HANDLE[4];
	for(int i = 1; i<=5;i++)
	{
		stringstream ss;
		ss << "res/Menu/Menu"<< i << ".bmp";
		hMenu[i-1] = LoadImage(NULL, ss.str().c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	}

	string s = "res/life.bmp";
	hLifeImage = LoadImage(NULL,s.c_str(),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

	string board = "res/Scoreboard.bmp";
	hScoreboard = LoadImage(NULL, board.c_str(),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

	showHighscores = false;
	mciSendString("open music/JohnnyBravo.mp3 type mpegvideo alias menuMusic", NULL, 0, 0);
	mciSendString("play menuMusic", NULL, 0, 0);

	CSoundPlayer::canPlay = false;
}

CBrocko::~CBrocko()
{
}


void CBrocko::GameLoop()
{
	GetSystemTime(&lastTime);
	long newTime = (lastTime.wSecond * 1000) + lastTime.wMilliseconds;

	int timeDif = diff_ms(newTime, lastMsTime);


	if(!input.shouldPause && playing){
		msqueue += timeDif;
		this->playingTime += timeDif;
	}

	if(msqueue >= 0){

		if(!input.shouldPause && playing){
			int i = world.Update(player.x);
			if(i != -1){
				CSoundPlayer::PlaySound1("music\\end.wav");
				if(i > 2){
					ReadHighscores read;
					Highscore* high = new  Highscore((playingTime / 1000), player.deaths, player.score);
					WritingScore* write = new WritingScore(read, high);
				}

				world.Init(&player, i,&hImage);
				return;
			}
			player.Update();
			msqueue  -= 16;
		}
	}
	if(msqueue < 0){
		CBrocko::Draw();
		if(!input.shouldPause && playing){
			frames++;
		}
	}

	this->handleMenu();
	this->handleSplashMenu();

	lastMsTime = newTime;
}

void CBrocko::GameEnd()
{
	//hsllo
	mciSendString("close myFile", NULL, 0, 0);
}

void CBrocko::GameInit()
{
	char picfile[] = "res/stars.bmp";
	hImage = LoadImage(NULL, picfile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		

	::GetClientRect(m_hWnd, &rect);
	//mciSendString("open music/test.mp3 type mpegvideo alias myFile", NULL, 0, 0);
	//mciSendString("play myFile", NULL, 0, 0);
}

void CBrocko::Draw()
{
	bufDC = CreateCompatibleDC(graphics);
	bufBMP = CreateCompatibleBitmap(graphics, rect.right, rect.bottom);
	SelectObject(bufDC, bufBMP);

	BITMAP bitmap;
	SIZE imgSize;
	RECT rect;

	GetObject(hImage, sizeof(BITMAP), &bitmap);

	imgSize.cx = bitmap.bmWidth;
	imgSize.cy = bitmap.bmHeight;

	HDC hImageDC = CreateCompatibleDC(bufDC);

	::GetClientRect(m_hWnd, &rect);
	FillRect(bufDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));

	SelectObject(hImageDC, hImage);
	BitBlt(bufDC, 0 ,0 ,imgSize.cx, imgSize.cy, hImageDC, 0, 0, SRCCOPY);

	//player.Draw(graphics, m_hWnd, bufDC, bufBMP);

	//	world.Draw(graphics, m_hWnd, bufDC, bufBMP);


	world.Draw(bufDC);
	player.Draw(bufDC);

	//draw deaths
	string deaths = "Deaths: " + player.getDeaths();
	SetBkMode(bufDC, TRANSPARENT);
	COLORREF clrWhite = RGB(255, 255, 255);
	SetTextColor(bufDC,clrWhite);
	TextOut(bufDC,10,10, deaths.c_str(), deaths.size());

	//draw health
	string strHealth = "Health: ";
	TextOut(bufDC,10,42, strHealth.c_str(), strHealth.size());
	for(int i = 0; i < player.health / 100; i++)
	{
		RenderHelper::RenderMenu(bufDC, hLifeImage, 70 + (i*42), 35, 32,32);
	}

	// draw score
	string score = "Score: " + player.getScore();
	TextOut(bufDC,100,10, score.c_str(), score.size());

	//draw playing time
	string playTime = "Time: " + getPlayingTime();
	TextOut(bufDC,200,10, playTime.c_str(), playTime.size());

	//draw fps
	if(playingTime > 0){
		string fps = "Average FPS: " + getFrames();

		TextOut(bufDC,650,10, fps.c_str(), fps.size());

		//draw tile index
		POINT pos;
		GetCursorPos(&pos);
		ScreenToClient(*handle, &pos);
		int tileX = 0;
		tileX = (pos.x+RenderHelper::viewX) / 32;
		int tileY = 0;
		tileY = (pos.y+RenderHelper::viewY) / 32;
		stringstream ss;
		ss << "(" << tileX <<", "<< tileY <<")";
		TextOut(bufDC,600,10, ss.str().c_str(), ss.str().size());	
	}

	//menu
	if(this->input.shouldPause)
	{
		RenderHelper::RenderMenu(bufDC,hMenu[menuItem-1],217,197,366,206);
	}

	if(!playing)
	{
		RenderHelper::RenderMenu(bufDC,hSplashMenu[(splashMenuItem-1)],0,0,800,600);
	}

	if(showHighscores)
	{
		RenderHelper::RenderMenu(bufDC,hScoreboard,214,35,372,275);

		stringstream high;
		high << "Time   -  Deaths  -  Points  -  Final score";
		TextOut(bufDC,275,85,high.str().c_str(),high.str().size());

		ReadHighscores read;
		Highscore* a[11];
		Highscore** h = read.GetHighscores();
		
		for(int i = 0; i < 10; i++){
			a[i] = h[i];
		}

		for(int i = 0; i < 9; i++){
			stringstream time;
			stringstream deaths;
			stringstream points;
			stringstream finalscore;
			int score = a[i]->points - a[i]->time - (a[i]->deaths * 20);
			if(score == 4690){
				score = 4690;
			}
			time << a[i]->time;
			deaths <<  "   -   " << a[i]->deaths;
			points <<  "   -   " << a[i]->points;
			finalscore << "   -   " << score;
			TextOut(bufDC,275,i*20+110,time.str().c_str(),time.str().size());
			TextOut(bufDC,320,i*20+110,deaths.str().c_str(),deaths.str().size());
			TextOut(bufDC,375,i*20+110,points.str().c_str(),points.str().size());
			TextOut(bufDC,435,i*20+110,finalscore.str().c_str(),finalscore.str().size());
		}

		if(input.shouldPause){
			showHighscores = false;
			input.shouldPause = false;
		}

	}
	if(world.finishedGame)
	{
		this->playing = false;
		this->showHighscores = true;
		if(!input.shouldPause){
			world.finishedGame = false;
		}
	}

	BitBlt(graphics, rect.left,rect.top, rect.right, rect.bottom,bufDC, 0, 0, SRCCOPY);

	DeleteDC(bufDC);
	DeleteDC(hImageDC);
	ReleaseDC(m_hWnd, bufDC);
	ReleaseDC(m_hWnd, hImageDC);

	DeleteObject(bufBMP);
}
/////////////////////////////////////
// Member functions                //
/////////////////////////////////////

LRESULT CBrocko::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	handle = &hWnd;
	return CWin::MsgProc(hWnd, uMsg, wParam, lParam);
}

int CBrocko::diff_ms(long tNieuw, long tOud)
{
	if(tNieuw >= tOud){ 
		return tNieuw - tOud;
	}
	else{
		tNieuw += 60000;
		return tNieuw - tOud;
	}
}

string CBrocko::getFrames()
{
	string frames;
	stringstream out;
	int time = (playingTime/1000);
	if(time == 0){
		time = 1;
	}
	out << (this->frames / time );
	frames = out.str();
	return frames;
}

string CBrocko::getPlayingTime()
{
	string time;
	stringstream out;

	out << (this->playingTime/ 1000);
	time = out.str();
	return time;
}

void CBrocko::handleMenu()
{
	if(input.shouldPause){
		//menu omlaag
		if(input.downPressed && !downAlreadyPressed)
		{
			downAlreadyPressed = true;
			if(menuItem+1 > 5)
				menuItem = 1;
			else{
				menuItem++;
			}
		}

		//menu omhoog
		if(input.upPressed && !upAlreadyPressed)
		{
			upAlreadyPressed = true;
			if(menuItem-1 < 1)
				menuItem = 5;
			else{
				menuItem--;
			}
		}

		if(!input.upPressed)
			upAlreadyPressed = false;
		if(!input.downPressed)
			downAlreadyPressed = false;

		//reset
		if(input.EnterPressed && menuItem == 1)
		{
			//world.Init(&player,2,&hImage);

			if(world.level == 1){
				world.LoadLevel1(&player);
				player.x = 0; player.y = 0;
				player.spawnX = 0;
				player.spawnY = 0;
				player.checkpoint = -1;
			}

			if(world.level == 2){
				world.LoadLevel2(&player);
				player.x = 16*32; player.y = 0;
				player.spawnX = 16*32;
				player.spawnY = 0;
				player.checkpoint = -1;
			}
			player.setXSpeed(0.0);
			player.setYSpeed(0.0);
			player.setDeaths(0);
			player.setScore(0);
			player.health = 100;
			this->playingTime = 0;
			this->frames = 0;
			player.waldoTime = 0;
			input.shouldPause = false;
		}

		//new game
		if(input.EnterPressed && menuItem == 2)
		{
			world.Init(&player,1,&hImage);
			world.LoadLevel1(&player);
			player.x = 0; player.y = 0;
			player.spawnX = 0;
			player.spawnY = 0;
			player.setXSpeed(0.0);
			player.setYSpeed(0.0);
			player.setDeaths(0);
			this->playingTime = 0;
			this->frames = 0;
			player.checkpoint = -1;
			player.waldoTime = 0;
			player.spawnX = 0;
			player.spawnY = 0;

			input.shouldPause = false;
		}

		//save game
		if(input.EnterPressed && menuItem == 3)
		{
			world.SaveGame((playingTime / 1000), &player);
			input.shouldPause = false;
		}

		//load game
		if(input.EnterPressed && menuItem == 4)
		{
			playingTime = world.LoadGame(&player, &hImage) * 1000;
			player.waldoTime = 0;
			input.shouldPause = false;
		}

		//quit game
		if(input.EnterPressed && menuItem == 5)
		{
			PostQuitMessage(0);
		}
	}

}

void CBrocko::handleSplashMenu()
{
	if(!playing)
	{
		if(input.upPressed && !upAlreadyPressed)
		{
			upAlreadyPressed = true;
			if(splashMenuItem-1 < 1)
				splashMenuItem = 4;
			else{
				splashMenuItem--;
			}
		}

		if(input.downPressed && !downAlreadyPressed)
		{
			downAlreadyPressed = true;
			if(splashMenuItem+1 > 4)
				splashMenuItem = 1;
			else{
				splashMenuItem++;
			}
		}

		if(!input.upPressed)
			upAlreadyPressed = false;
		if(!input.downPressed)
			downAlreadyPressed = false;

		//new game
		if(input.EnterPressed && splashMenuItem == 1)
		{
			playing = true;
			CSoundPlayer::PlaySound1("music\\beginning.wav");
			mciSendString("stop menuMusic", NULL, 0, 0);
			showHighscores = false;
			
			world.Init(&player,1,&hImage);
			world.LoadLevel1(&player);
			player.x = 0; player.y = 0;
			player.setXSpeed(0.0);
			player.setYSpeed(0.0);
			player.setDeaths(0);
			this->playingTime = 0;
			this->frames = 0;
			player.checkpoint = -1;
			player.waldoTime = 0;
			player.spawnX = 0;
			player.spawnY = 0;

			input.shouldPause = false;
		}
		//load game
		if(input.EnterPressed && splashMenuItem == 2)
		{
			playingTime = world.LoadGame(&player, &hImage) * 1000;
			showHighscores = false;
			playing = true;
			mciSendString("stop menuMusic", NULL, 0, 0);
		}
		//highscores
		if(input.EnterPressed && splashMenuItem == 3)
		{
			showHighscores = true;
		}
		//quit
		if(input.EnterPressed && splashMenuItem == 4)
		{
			PostQuitMessage(0);
		}

		Draw();
	}
	

}